home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / WINPROGS.ARJ / TYPER.C < prev    next >
Text File  |  1990-11-24  |  8KB  |  275 lines

  1. /*   typer.c   -   Typing Program
  2.                    Petzold
  3. */
  4.  
  5. #include <windows.h>
  6. #include <stdlib.h>
  7.  
  8. #define BUFFER(x,y) *(pBuffer + y * cxBuffer + x)
  9.  
  10. long FAR PASCAL WndProc (HWND, WORD, WORD, LONG);
  11.  
  12. int PASCAL WinMain (HANDLE hInstance,
  13.                     HANDLE hPrevInstance,
  14.                     LPSTR  lpszCmdParam,
  15.                     int    nCmdShow)
  16.                     
  17.   {
  18.   static char szAppName[] = "Typer";
  19.   HWND        hwnd;
  20.   MSG         msg;
  21.   WNDCLASS    wndclass;
  22.   
  23.   if (!hPrevInstance)
  24.      {
  25.      wndclass.style            = CS_HREDRAW | CS_VREDRAW;
  26.      wndclass.lpfnWndProc      = WndProc;
  27.      wndclass.cbClsExtra       = 0;
  28.      wndclass.cbWndExtra       = 0;
  29.      wndclass.hInstance        = hInstance;
  30.      wndclass.hIcon            = LoadIcon (NULL, IDI_APPLICATION);
  31.      wndclass.hCursor          = LoadCursor (NULL, IDC_ARROW);
  32.      wndclass.hbrBackground    = GetStockObject (WHITE_BRUSH);
  33.      wndclass.lpszMenuName     = NULL;
  34.      wndclass.lpszClassName    = szAppName;
  35.      
  36.      RegisterClass(&wndclass);
  37.      }
  38.      
  39.   hwnd = CreateWindow (szAppName,
  40.                        "Typing Program",
  41.                        WS_OVERLAPPEDWINDOW, 
  42.                        CW_USEDEFAULT,   
  43.                        CW_USEDEFAULT,
  44.                        CW_USEDEFAULT,   
  45.                        CW_USEDEFAULT,   
  46.                        NULL,
  47.                        NULL,
  48.                        hInstance,
  49.                        NULL);
  50.                        
  51.   ShowWindow (hwnd, nCmdShow);
  52.   UpdateWindow (hwnd);
  53.   
  54.   while (GetMessage (&msg, NULL, 0, 0))
  55.     {
  56.     TranslateMessage (&msg);
  57.     DispatchMessage  (&msg);
  58.     }
  59.     
  60.   return msg.wParam;
  61.   }
  62.   
  63. long FAR PASCAL WndProc (HWND hwnd,
  64.                          WORD message,
  65.                          WORD wParam,
  66.                          LONG lParam)
  67.                          
  68.   {
  69.   static char  *pBuffer = NULL;
  70.   static int   cxChar, cyChar, cxClient, cyClient, cxBuffer, cyBuffer,
  71.                xCaret, yCaret;
  72.   int          x, y, i;
  73.   TEXTMETRIC   tm;
  74.   HDC          hdc;
  75.   PAINTSTRUCT  ps;
  76.   
  77.   switch (message)
  78.     {
  79.     case WM_CREATE:
  80.       hdc = GetDC (hwnd);
  81.       
  82.       SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT));
  83.       GetTextMetrics (hdc, &tm);
  84.       cxChar = tm.tmAveCharWidth;
  85.       cyChar = tm.tmHeight;
  86.       
  87.       ReleaseDC (hwnd, hdc);
  88.       return 0;
  89.       
  90.     case WM_SIZE:
  91.       cyClient = HIWORD (lParam);
  92.       cxClient = LOWORD (lParam);
  93.  
  94.       cxBuffer = max (1, cxClient / cxChar);
  95.       cyBuffer = max (1, cyClient / cyChar);
  96.       
  97.       if (pBuffer != NULL)
  98.         free (pBuffer);
  99.         
  100.       if ((LONG) cxBuffer * cyBuffer > 65535L ||
  101.                  (pBuffer = malloc (cxBuffer * cyBuffer)) == NULL)
  102.                  
  103.         MessageBox (hwnd, "Window too Large.  Cannot "
  104.                           "allocate enough memory.", "Type",
  105.                           MB_ICONEXCLAMATION | MB_OK);
  106.       
  107.       else
  108.         for (y = 0; y < cyBuffer; y++)
  109.           for (x = 0; x < cxBuffer; x++)
  110.             BUFFER(x,y) = ' ';
  111.             
  112.       xCaret = 0;
  113.       yCaret = 0;
  114.       
  115.       if (hwnd == GetFocus ())
  116.         SetCaretPos (xCaret * cxChar, yCaret * cyChar);
  117.                                             
  118.       return 0;
  119.       
  120.     case WM_SETFOCUS:
  121.       CreateCaret (hwnd, NULL, cxChar, cyChar);
  122.       SetCaretPos (xCaret * cxChar, yCaret * cyChar);
  123.       ShowCaret (hwnd);
  124.       return 0;
  125.       
  126.     case WM_KILLFOCUS:
  127.       HideCaret (hwnd);
  128.       DestroyCaret ();
  129.       return 0;
  130.           
  131.     case WM_KEYDOWN:
  132.       switch (wParam)
  133.         {
  134.         case VK_HOME:
  135.           xCaret = 0;
  136.           break;
  137.         
  138.         case VK_END:
  139.           xCaret = cxBuffer -1;
  140.           break;
  141.                                          
  142.         case VK_PRIOR:
  143.           yCaret = 0;
  144.           break;
  145.                                                   
  146.         case VK_NEXT:
  147.           yCaret = cyBuffer - 1;
  148.           break;
  149.                                                     
  150.         case VK_UP:
  151.           yCaret = max (yCaret - 1, 0);
  152.           break;
  153.                   
  154.         case VK_DOWN:
  155.           yCaret = min (yCaret + 1, cyBuffer - 1);
  156.           break;
  157.           
  158.         case VK_LEFT:
  159.           xCaret = max (xCaret - 1, 0);
  160.           break;
  161.                                                             
  162.         case VK_RIGHT:
  163.           xCaret = min (xCaret + 1, cxBuffer - 1);
  164.           break;
  165.           
  166.         case VK_DELETE:
  167.           for (x - xCaret; x < cxBuffer - 1; x++)
  168.             BUFFER(x,yCaret) = BUFFER(x+1,yCaret);
  169.           
  170.           BUFFER(cxBuffer -1,yCaret) = ' ';
  171.           
  172.           HideCaret (hwnd);
  173.           hdc = GetDC (hwnd);
  174.           
  175.           SelectObject (hdc, 
  176.                         GetStockObject (SYSTEM_FIXED_FONT));
  177.                              
  178.           TextOut (hdc, xCaret * cxChar, yCaret * cyChar,
  179.                    &BUFFER(xCaret,yCaret),
  180.                    cxBuffer - xCaret);
  181.                    
  182.            ShowCaret (hwnd);
  183.            ReleaseDC (hwnd, hdc);
  184.            break;
  185.                                                       
  186.         case WM_CHAR:
  187.           for (i = 0; i < LOWORD (lParam); i++)
  188.             {
  189.             switch (wParam)
  190.               {
  191.               case '\b':
  192.                 if (xCaret > 0)
  193.                   {
  194.                   xCaret--;
  195.                   SendMessage (hwnd, WM_KEYDOWN, VK_DELETE, 1L);
  196.                   }
  197.                 break;
  198.                 
  199.               case '\t':
  200.                 do
  201.                   {
  202.                   SendMessage (hwnd, WM_CHAR, ' ', 1L);
  203.                   }
  204.                 while (xCaret % 8 != 0);
  205.                 break;
  206.                 
  207.               case '\n':
  208.                 if(++yCaret == cyBuffer)
  209.                   yCaret = 0;
  210.                 break;
  211.                 
  212.               case '\r':
  213.                 xCaret = 0;
  214.                 
  215.                 if (++yCaret == cyBuffer)
  216.                   yCaret = 0;
  217.                 break;
  218.                 
  219.               case '\x1B':
  220.                 for (y = 0; y < cyBuffer; y++)
  221.                   for (x = 0; x < cxBuffer; x++)
  222.                     BUFFER(x,y) = ' ';
  223.                     
  224.                 xCaret = 0;
  225.                 yCaret = 0;
  226.                 InvalidateRect (hwnd, NULL, FALSE);
  227.                 break;
  228.                 
  229.               default:
  230.                 BUFFER(xCaret, yCaret) = (char) wParam;
  231.                 
  232.                 HideCaret (hwnd);
  233.                 hdc = GetDC(hwnd);
  234.                 
  235.                 SelectObject (hdc,
  236.                               GetStockObject (SYSTEM_FIXED_FONT));
  237.                                    
  238.                 TextOut (hdc, xCaret * cxChar, yCaret * cyChar,
  239.                          &BUFFER(xCaret,yCaret), 1);
  240.                          
  241.                 ShowCaret (hwnd);
  242.                 ReleaseDC (hwnd, hdc);
  243.                 
  244.                 if (++xCaret == cxBuffer)
  245.                   {
  246.                   xCaret = 0;
  247.                   if (++yCaret == cyBuffer)
  248.                     yCaret = 0;
  249.                   }
  250.                 break;
  251.               }
  252.             }
  253.           SetCaretPos (xCaret * cxChar, yCaret * cyChar);
  254.           return 0;
  255.           
  256.               
  257.     case WM_PAINT:
  258.       hdc = BeginPaint (hwnd, &ps);
  259.       SelectObject (hdc,
  260.                     GetStockObject (SYSTEM_FIXED_FONT));
  261.       
  262.       for (y = 0; y < cyBuffer; y++)
  263.         TextOut (hdc, 0, y * cyChar, &BUFFER(0,y), cxBuffer);
  264.         
  265.       EndPaint (hwnd, &ps);
  266.       return 0;
  267.          
  268.     case WM_DESTROY:
  269.       PostQuitMessage (0);
  270.       return 0;
  271.     }
  272.     
  273.   return DefWindowProc (hwnd, message, wParam, lParam);
  274.   }
  275.